# !/usr/bin/env python
# -*- coding: utf-8 -*-
import json
from typing import List
from json import JSONEncoder
from enum import Enum
from util.func import Func

class ColType(Enum):
    INT = "int"
    BIGINT = "bigint"
    VARCHAR = "varchar"
    CHAR = "char"
    DATETIME = "datetime"
    DATE = "date"
    TIME = "time"
    DECIMAL = "decimal"

    @classmethod
    def from_type(cls, type):
        return cls(type)


class ClassEncoder(JSONEncoder):
    def default(self, obj):
        return obj.__dict__


class Column:
    def __init__(self, name=str, col_type=str, size=int) -> None:
        super().__init__()
        self.name = name
        self.alias = Func.first_camel(self.name)
        self.camel = Func.camel(self.name)
        self.type = col_type
        self.size = size
        self.comment = ''
        self.index = ''
        self.require = False
        self.default = ''
        self.auto_increment = False
        self.form = ""
        self.data = []
        self.ref = ""

    def __iter__(self):
        yield from {
            "name": self.name,
            "alias": self.alias,
            "camel": self.camel,
            "type": self.type,
            "size": self.size,
            "comment": self.comment,
            "index": self.index,
            "require": self.require,
            "default": self.default,
            "auto_increment": self.auto_increment,
            "form": self.form,
            "data": self.data,
            "ref": self.ref
        }.items()

    def __str__(self):
        return json.dumps(dict(self), ensure_ascii=False, cls=ClassEncoder)

    def __repr__(self):
        return self.__str__()


class Table:
    def __init__(self, name=str, comment=str, columns=List[Column]) -> None:
        super().__init__()
        self.name = name
        self.alias = Func.first_camel(self.name)
        self.camel = Func.camel(self.name)
        self.comment = comment
        self.enable = True
        self.columns = columns

    def __iter__(self):
        yield from {
            "name": self.name,
            "alias": self.alias,
            "camel": self.camel,
            "comment": self.comment,
            "columns": self.columns,
            "enable": self.enable
        }.items()

    def __str__(self):
        return json.dumps(dict(self), ensure_ascii=False, cls=ClassEncoder)

    def __repr__(self):
        return self.__str__()


class Template:
    def __init__(self, name=str, file_type=str, type=str) -> None:
        super().__init__()
        self.name = name
        self.enable = True
        self.file_type = file_type
        # name,alias,camel
        self.name_type = 'name'
        self.type = type
        self.suffix = ""
        self.prefix = ""
        self.module = ""

    def __iter__(self):
        yield from {
            "name": self.name,
            "enable": self.enable,
            "suffix": self.suffix,
            "prefix": self.prefix,
            "type": self.type,
            "file_type": self.file_type,
            "name_type": self.name_type,
            "module": self.module
        }.items()

    def __str__(self):
        return json.dumps(dict(self), ensure_ascii=False, cls=ClassEncoder)

    def __repr__(self):
        return self.__str__()


class Schema:
    def __init__(self, author=str, db=str, tables=List[Table]) -> None:
        super().__init__()
        self.package = ""
        self.author = author
        self.db = db
        self.database = ""
        self.templates = []
        self.tables = tables
        self.engines = []

    def __iter__(self):
        yield from {
            "package": self.package,
            "author": self.author,
            "db": self.db,
            "database": self.database,
            "templates": self.templates,
            "tables": self.tables,
            "engines": self.engines
        }.items()

    def __str__(self):
        return json.dumps(dict(self), ensure_ascii=False, cls=ClassEncoder)

    def __repr__(self):
        return self.__str__()
